<!-- src/components/ui/Tabs.vue -->

<template>
  <div class="tabs-container">
    <div class="tabs-header border-b px-1.5 flex justify-between">
      <div class="tabs-nav overflow-hidden flex-1 pos-relative">
        <span
          class="flex px-2.5 bg-white h-full hover:cursor-pointer opacity-90 hover:opacity-100 transition scroll-btn left"
          style="z-index: 10"
          @click="scrollPrev()"
          :disabled="!canScrollLeft"
          v-show="showScrollButtons"
        >
          <el-icon class="m-auto"><i-ep-ArrowLeft /> </el-icon>
        </span>
        <div class="pt-1.5 flex-1 overflow-hidden pos-relative" ref="tabsContainerRef">
          <div
            class="tabs-nav-scroll flex transition"
            :style="{ transform: `translateX(${translateX}px)` }"
            ref="tabsScrollRef"
          >
            <div
              v-for="(tab, index) in tabs"
              :key="tab.path"
              class="tab-item pos-relative inline-flex -mr-0.5"
              :class="{ active: isActive(tab) }"
              @click="handleTabClick(tab, index)"
              @contextmenu.prevent="handleContextMenu($event, tab)"
            >
              <div
                class="pos-relative flex items-center h-full px-2.5 transition"
                style="z-index: 5"
                :class="index == 0 ? 'px-1' : ''"
              >
                {{ tab.icon }}
                <span class="i-codicon-list-ordered text-base text-icon mr-1"></span>
                <span class="text-sm text-primary" style="white-space: nowrap">{{
                  tab.title
                }}</span>
                <el-icon
                  class="text-icon"
                  :size="16"
                  v-if="index == 0"
                  @click.stop="handleClose(tab)"
                >
                  <Paperclip class="text-icon" />
                </el-icon>
                <el-icon :size="16" v-else @click.stop="handleClose(tab)">
                  <Close class="text-icon" />
                </el-icon>
              </div>

              <!-- 特殊形状背景层 -->
              <div class="tab-item-bg pos-absolute transition">
                <svg
                  data-v-41cc7a2b=""
                  class="tab-item-bg-before group-[.is-active]:fill-primary/15 dark:group-[.is-active]:fill-accent absolute bottom-0 left-[-1px] transition-all duration-150"
                  height="7"
                  width="7"
                >
                  <path data-v-41cc7a2b="" d="M 0 7 A 7 7 0 0 0 7 0 L 7 7 Z"></path>
                </svg>
                <div class="tab-item-bg-center"></div>
                <svg
                  data-v-41cc7a2b=""
                  class="tab-item-bg-after group-[.is-active]:fill-primary/15 dark:group-[.is-active]:fill-accent absolute bottom-0 right-[-1px] transition-all duration-150"
                  height="7"
                  width="7"
                >
                  <path data-v-41cc7a2b="" d="M 0 0 A 7 7 0 0 0 7 7 L 0 7 Z"></path>
                </svg>
              </div>
            </div>
          </div>
        </div>
        <span
          class="flex px-2.5 bg-white h-full hover:cursor-pointer opacity-90 hover:opacity-100 transition scroll-btn right"
          style="z-index: 10"
          @click="scrollNext"
          :disabled="!canScrollRight"
          v-show="showScrollButtons"
        >
          <el-icon class="m-auto"><i-ep-ArrowRight /> </el-icon>
        </span>
      </div>
      <slot />
    </div>
  </div>
</template>
<script lang="ts" setup>
import { ref, onMounted, watch, nextTick, computed, onUnmounted } from "vue";
import { useRoute, useRouter } from "vue-router";
import { Close, Paperclip } from "@element-plus/icons-vue";

interface TabItem {
  title: string;
  path: string;
  fullPath: string;
  icon?: string;
}

const route = useRoute();
const router = useRouter();
console.log("路由信息：", route);
const tabsScrollRef = ref<HTMLElement | null>(null);
const tabsContainerRef = ref<HTMLElement | null>(null);
const currentIndex = ref(0);
const translateX = ref(0);
const maxTranslateX = ref(0);
// 标签页列表
const tabs = ref<TabItem[]>([]);
// 缓存的视图名称
const cachedViews = ref<string[]>([]);

// 滚动状态
const isDragging = ref(false);
const startX = ref(0);
const startScrollOffset = ref(0);
const showScrollButtons = ref(false);
// 当前激活的标签页
const isActive = (tab: TabItem) => {
  return tab.path === route.path;
};

// 初始化标签页
const initTabs = () => {
  console.log(route);
  if (tabs.value.some((tab) => tab.path === route.path)) return;

  // ✅ 1. 确保首页标签始终存在
  const homeTab = {
    title: "首页",
    path: "/home",
    fullPath: "/home",
  };

  if (!tabs.value.some((tab) => tab.path === "/home")) {
    tabs.value.unshift(homeTab); // 放在第一个位置
  }

  // ✅ 2. 如果是根路径 /，则跳转到首页
  if (route.path === "/") {
    router.replace("/home"); // 使用 replace 避免历史记录污染
    return;
  }

  // ✅ 3. 其他路由正常处理
  if (tabs.value.some((tab) => tab.path === route.path)) return;

  if (!route.meta.title) {
    router.push("/404"); // 默认回退到首页
    return;
  }
  tabs.value.push({
    title: (route.meta.title as string) || "未命名",
    path: route.path,
    fullPath: route.fullPath,
  });
  console.log("路由元信息:", route.meta);
  if (route.meta.keepAlive) {
    cachedViews.value.push(route.name as string);
  }
};

// 点击标签页
const handleTabClick = (tab: TabItem, index: number) => {
  currentIndex.value = index;
  router.push(tab.fullPath);
};

// 关闭标签页
const handleClose = (tab: TabItem) => {
  const index = tabs.value.findIndex((item) => item.path === tab.path);
  if (index === -1) return;

  // 如果关闭的是当前激活的标签页
  if (isActive(tab)) {
    const prevTab = tabs.value[index - 1] || tabs.value[index + 1];
    if (prevTab) {
      router.push(prevTab.fullPath);
    } else {
      router.push("/");
    }
  }

  // 从缓存中移除
  if (route.meta.keepAlive) {
    const cachedIndex = cachedViews.value.indexOf(route.name as string);
    if (cachedIndex > -1) {
      cachedViews.value.splice(cachedIndex, 1);
    }
  }

  tabs.value.splice(index, 1);
};

// 右键菜单
const handleContextMenu = (_e: MouseEvent, tab: TabItem) => {
  // 这里可以实现右键菜单功能
  console.log("右键点击:", tab);
};
const calculateScrollPosition = () => {
  nextTick(() => {
    if (!tabsScrollRef.value || !tabsContainerRef.value) return;

    const containerWidth = tabsContainerRef.value.offsetWidth;
    const scrollWidth = tabsScrollRef.value.scrollWidth;

    // 只有当标签组总宽度超过容器宽度时才计算偏移量
    if (scrollWidth <= containerWidth) {
      translateX.value = 0; // 无偏移
      return;
    }

    maxTranslateX.value = containerWidth - scrollWidth; // 最大负偏移量

    // 查找当前激活的页签
    const activeTabIndex = tabs.value.findIndex((tab) => isActive(tab));
    if (activeTabIndex === -1) return;

    // 获取当前页签元素
    const tabElements = tabsScrollRef.value.querySelectorAll(".tab-item");
    if (!tabElements[activeTabIndex]) return;

    const tab = tabElements[activeTabIndex] as HTMLElement;
    const tabLeft = tab.offsetLeft;
    const tabWidth = tab.offsetWidth;
    const containerCenter = containerWidth / 2;

    // 计算目标偏移量 - 使当前标签居中
    let targetX = containerCenter - (tabLeft + tabWidth / 2);

    // 确保偏移量在有效范围内
    targetX = Math.max(maxTranslateX.value, Math.min(0, targetX));

    translateX.value = targetX;
  });
};
// 自动滚动到当前激活页签
const scrollToActiveTab = () => {
  nextTick(() => {
    if (!tabsContainerRef.value || !tabsScrollRef.value) return;

    const activeTab = document.querySelector(".tab-item.active");
    if (!activeTab) return;

    const tabRect = activeTab.getBoundingClientRect();
    const wrapperRect = tabsContainerRef.value.getBoundingClientRect();

    // 如果标签在左侧外
    if (tabRect.left < wrapperRect.left) {
      translateX.value += wrapperRect.left - tabRect.left + 10;
    }
    // 如果标签在右侧外
    else if (tabRect.right > wrapperRect.right) {
      translateX.value -= tabRect.right - wrapperRect.right + 10;
    }

    // 确保不超出边界
    const maxOffset = 0;
    const minOffset =
      tabsContainerRef.value.offsetWidth - tabsScrollRef.value.offsetWidth;
    translateX.value = Math.max(minOffset, Math.min(maxOffset, translateX.value));
  });
};

const scrollPrev = () => {
  console.log("scrollPrev", translateX.value);
  if (!tabsContainerRef.value) return;
  const newOffset = Math.min(
    0,
    translateX.value + tabsContainerRef.value.offsetWidth * 0.8
  );
  console.log("scrollLeft", newOffset);
  translateX.value = newOffset;
};
const scrollNext = () => {
  if (!tabsContainerRef.value || !tabsScrollRef.value) {
    console.error("DOM元素未准备好");
    return;
  }
  // 计算最大可滚动距离（负数）
  const maxOffset = tabsContainerRef.value.offsetWidth - tabsScrollRef.value.scrollWidth;
  console.log("最大偏移:", maxOffset);

  // 计算新偏移量（每次滚动容器宽度的80%）
  const scrollAmount = tabsContainerRef.value.offsetWidth * 0.8;
  const newOffset = translateX.value - scrollAmount;

  // 确保不会滚动超过最大偏移量
  const clampedOffset = Math.max(maxOffset, newOffset);
  console.log("计算后的新偏移:", clampedOffset);

  translateX.value = clampedOffset;
  translateX.value -= 100;
};

// 拖拽功能
const startDrag = (e: MouseEvent) => {
  if (!tabsScrollRef.value) return;

  isDragging.value = true;
  startX.value = e.clientX;
  startScrollOffset.value = translateX.value;

  document.addEventListener("mousemove", handleDrag);
  document.addEventListener("mouseup", stopDrag);
  tabsScrollRef.value.style.cursor = "grabbing";
  tabsScrollRef.value.style.transition = "none";
};

const handleDrag = (e: MouseEvent) => {
  if (!isDragging.value || !tabsContainerRef.value || !tabsScrollRef.value) return;

  const deltaX = e.clientX - startX.value;
  let newOffset = startScrollOffset.value + deltaX;

  // 限制滚动范围
  const maxOffset = 0;
  const minOffset = tabsContainerRef.value.offsetWidth - tabsScrollRef.value.offsetWidth;
  newOffset = Math.max(minOffset, Math.min(maxOffset, newOffset));

  translateX.value = newOffset;
};

const stopDrag = () => {
  isDragging.value = false;
  if (tabsScrollRef.value) {
    tabsScrollRef.value.style.cursor = "";
    tabsScrollRef.value.style.transition = "transform 0.3s ease";
  }
  document.removeEventListener("mousemove", handleDrag);
  document.removeEventListener("mouseup", stopDrag);
};

// 鼠标滚轮滚动
const handleWheel = (e: WheelEvent) => {
  if (!tabsContainerRef.value) return;

  // 水平滚动
  if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) {
    e.preventDefault();
    translateX.value = Math.max(
      tabsContainerRef.value.offsetWidth - (tabsScrollRef.value?.offsetWidth || 0),
      Math.min(0, translateX.value + e.deltaX)
    );
  }
};
// 监听路由变化
watch(
  () => route.path,
  () => {
    initTabs();
    calculateScrollPosition();
  },
  { immediate: true }
);
// 监听tabs变化
watch(
  () => tabs.value.length,
  () => {
    calculateScrollPosition();
    checkScrollButtons();
    scrollToActiveTab();
  }
);

// 检查是否需要显示滚动按钮
const checkScrollButtons = () => {
  if (!tabsContainerRef.value || !tabsScrollRef.value) {
    showScrollButtons.value = false;
    return;
  }

  showScrollButtons.value =
    tabsScrollRef.value.scrollWidth > tabsContainerRef.value.offsetWidth;
};
// 计算属性
const canScrollLeft = computed(() => translateX.value < 0);
const canScrollRight = computed(() => {
  if (!tabsContainerRef.value || !tabsScrollRef.value) return false;
  console.log(
    tabsScrollRef.value.scrollWidth,
    translateX.value,
    tabsContainerRef.value.offsetWidth
  );
  return (
    tabsScrollRef.value.scrollWidth + translateX.value >
    tabsContainerRef.value.offsetWidth
  );
});
// 组件挂载时计算
onMounted(async () => {
  await nextTick();
  window.addEventListener("resize", checkScrollButtons);
  calculateScrollPosition();
  checkScrollButtons();
});
onUnmounted(() => {
  window.removeEventListener("resize", checkScrollButtons);
  stopDrag();
});
</script>
<style scoped lang="scss">
// 定义变量
$active-color: var(--el-color-primary);
$bg-active-color: var(--bg-active-color);
$bg-page-color: var(--bg-page-color);
$text-secondary: var(--text-color-secondary);
$text-primary: var(--text-color-primary);
$border-color: #e6e6e6;
$tab-height: 34px;
$tab-padding: 0 3.5px;
$radius: 4px;
$transition: all 0.3s ease;

.tabs-container {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.tabs-header {
  background-color: var(--primary-light-color);
  padding: 0 1.5px;
}

.tabs-nav {
  display: flex;
  position: relative;

  &-scroll {
    flex: 1;
    transition: transform 0.3s ease;
    white-space: nowrap;
  }
}

// 标签项样式
.tab-item {
  position: relative;
  padding: $tab-padding;
  height: $tab-height;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  border-radius: $radius $radius 0 0;
  transition: $transition;
  z-index: 2;

  // 悬停效果
  &::after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: calc(100% - 1px);
    background-color: $bg-page-color;
    z-index: -1;
    opacity: 0;
    border-radius: 5px;
    transition: $transition;
  }

  &:hover {
    color: $active-color;

    &::after {
      opacity: 1;
    }
  }

  // 激活状态
  &.active {
    color: $active-color;
    font-weight: bold;

    .tab-item-bg {
      display: block;
    }

    &::after {
      opacity: 0 !important;
    }
  }

  // 图标样式
  .el-icon {
    margin-left: 5px;
    font-size: 12px;
    border-radius: 50%;
    padding: 1px;
    transition: $transition;

    &:hover {
      background: $border-color;
      color: #f56c6c;
    }
  }
}

// 标签背景样式
.tab-item-bg {
  position: absolute;
  width: 100%;
  height: 100%;
  left: 0;
  bottom: 0;
  z-index: 1;
  display: none;

  &-before,
  &-after {
    fill: $bg-active-color;
  }

  &-center {
    background-color: $bg-active-color;
    width: calc(100% - 10px);
    height: 100%;
    margin: 0 auto;
    border-top-left-radius: 10px;
    border-top-right-radius: 10px;
  }
}

// 滚动按钮
.scroll-btn {
  width: 28px;
  height: 100%;
  background: var(--primary-light-color);
  border: none;
  outline: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  color: $text-secondary;
  z-index: 1;
  transition: $transition;

  &:disabled {
    opacity: 0.3;
    cursor: not-allowed;
  }

  &:not(:disabled):hover {
    background: var(--primary-light-color);
    color: $text-primary;
  }

  &.left {
    box-shadow: 4px 0 8px rgba(0, 0, 0, 0.05);
  }

  &.right {
    box-shadow: -4px 0 8px rgba(0, 0, 0, 0.05);
  }
}

// 工具类
.opacity-50 {
  opacity: 0.5;
}

.cursor-not-allowed {
  cursor: not-allowed;
}

.tabs-content {
  flex: 1;
  overflow: auto;
  background: #fff;
  padding: 15px;
}

.tab-component {
  height: 100%;
}
</style>
